# Guia de referencia NEXT.js 

### Contenido:

- [Crear Un Simple Proyecto Con NEXT.js](#crear-un-simple-proyecto-con-nextjs)
- [Crear Una Pagina Principal](#crear-una-pagina-principal)
- [Navegar Entre Paginas](#navegar-entre-paginas)
- [Usando Componentes Compartidos](#usando-componentes-compartidos)
- [Creando Paginas Dinamicas](#creando-paginas-dinamicas)
- [URLs Limpias y Enmascaramiento de Rutas](#urls-limpias-y-enmascaramiento-de-rutas)
- [Soporte para URLs Limpias del Lado del Servidor](#soporte-para-urls-limpias-del-lado-del-servidor)

[NEXT.js](https://nextjs.org) es un "Framework" de JavaScript creado para construir aplicaciones web interpretadas del lado de servidor y páginas estáticas utilizando [React](https://es.reactjs.org).

Algunas características de NEXT.js son:
+ **Páginas Interpretadas del lado del Servidor**: En dispositivos lentos, dibujar una página inicial puede tomar más tiempo y llevar a una experiencia degradada. Llevando la computación a un servidor más poderoso, se minimiza el tiempo que los usuarios pasan esperando.
+ **Exportación Estática**: Los sitios estáticos pueden desplegarse a una [CDN](https://es.wikipedia.org/wiki/Red_de_distribuci%C3%B3n_de_contenidos) (Red de Distribución de Contenidos) para obtener una latencia mínima, cero carga de servidor y entrega global mas rápida.
+ **CSS dentro de JS**: Next.js viene con `styled-jsx` integrado, así que no necesitas configurar demasiado y puedes construír páginas bien diseñadas.
+ **Cero Configuración**: División de código, ruteo basado en el sistema de archivos y recarga de código en caliente.
+ **Totalmente Extensible**: Completo control sobre [Babel](https://babeljs.io) y [Webpack](https://webpack.js.org). Servidor configurable, y extensiones para ruteo.
+ **Listo para Producción**: Optimizado para menor tamaño a la hora de construir para producción, compilación más rápida.

## Crear Un Simple Proyecto Con NEXT.js

Para crear un simple proyecto con NEXT.js, en la terminal ejecutar los siguientes comandos, sustituyendo lo que está entre `<>` con el nombre que quieras darle a tu proyecto:

```bash
$ mkdir <mi-proyecto>
$ cd <mi-proyecto>
$ npm init -y
$ npm install --save react react-dom next
$ mkdir pages
```

Después edita el archivo `package.json` agregando los siguientes scripts NPM:

```json
{
  "scripts": {
    "dev" : "next",
    "build" : "next build",
    "start" : "next start"
  }
}
```

Una vez que guardas el archivo `package.json` con los cambios, puedes ejecutar el siguiente comando para comenzar el servidor de desarrollo:

```bash
$ npm run dev
```

Entonces abre [localhost](http://localhost:3000) en tu navegador web favorito para ver lo que se construye.

## Crear Una Pagina Principal

Dentro del directorio `pages` creado previamente, crea un archivo llamado `index.js`:

```bash
$ touch pages/index.js
```

Agrega el siguiente contenido:

```javascript
// pages/index.js

const Index = () => (
  <div>
    <p>Hello Next.js</p>
  </div>
)

export default Index
```

> **Nota**: Asegurate que tu componente sea exportado por defecto con `export default`

Si cometiste algún error sintáctico se mostrará en la pantalla del navegador.

## Navegar Entre Páginas

Una vez que sabemos como crear una simple aplicación Next.js y ejecutarla podemos agregar más páginas y navegar entre ellas. Podemos agregar tantas páginas como queramos. Por ejemplo si queremos agregar una página de ayuda que complemente nuestra página principal, podemos crear una página "Help" agregando el siguiente contenido a `pages/help.js`:

```javascript
// pages/help.js

export default function Help() {
  return (
    <div>
      <p>This is the help page</p>
    </div>
  )
}
```

Entonces podemos acceder a ella con la ruta: <http://localhost:3000/help>.

Después de eso, necesitamos conectar nuestra página "Help" con nuestro "Index". Podríamos usar sólo una etiqueta `<a>` para eso, pero no proporcionaría navegación del lado del cliente, es decir, se navegaría a la página a través del servidor, que es precisamente lo que queremos evitar (hacer peticiones al servidor). Por ejemplo, esto hace petición "get" al servidor:

```javascript
// pages/index.js

const Index = () => (
  <div>
    <a href="/help">Help</a> // INCORRECTO !! Esto hace una peticion `GET /help` al servidor.
    <p>Hello Next.js</p>
  </div>
)
```

Para dar soporte de navegación del lado del cliente, necesitamos utilizar la API de Next.js, la cual tiene un componente llamado `Link`. Podemos acceder a el importando el componente con `next/link`.

```javascript
// pages/index.js

// Necesitamos esto para acceder a Link
import Link from 'next/link'

const Index = () => (
  <div>
    <Link href="/help"> // CORRECTO !! Esto no hace una peticion al servidor, simplemente dibuja la pagina
      <a>Help</a>       // No necesitas agregar href=... al `<a>`, Next.js lo inserta al compilar el codigo.
    </Link>
  </div>
)

export default Index
```

Ahora puedes visitar "Help" nuevamente a traves del `Link` que hay en el `Index`: <http://localhost:3000>

> Esto es navegación del lado del cliente (serverless); la acción se realiza en el navegador, sin hacer una petición al servidor. Puedes verificar esto abriendo el inspector de peticiones de red de tu navegador web[1].

Algo más que puedes comprobar es haciendo clic en el botón "Back" del navegador para ver el historial, `next/link` administra `location.history` por defecto. No necesitas escribir código de ruteo, solo agrega el componente `Link` a tus rutas.

### Agregar atributos a los vínculos

Si necesitas agregar attributos o propiedades a un vínculo por alguna razón. Quiza necesitas un atributo `title` al vínculo. Puedes hacer esto, por ejemplo:

```html
<Link href="/help">
  <a title="Help page">Help</a>
</Link>
```

Cuando agregas este atributo, puedes observar en el navegador que la etiqueta `<a>` que se dibuja en el navegador, se muestra al posicionar el puntero del ratón encima del vínculo. Pero que sucede si lo agregas al componente `Link`:

```html
<Link href="/help" title="Help page">
  <a>Help</a>
</Link>
```

De hecho, si agregas el atributo title al componente `Link` no tiene ningún efecto. Esto sucede porque `next/link` es solo un [Componente de Orden Superior](https://es.reactjs.org/docs/higher-order-components.html) que solo acepta la propiedad "href" y otros similares. Si necesitas agregar propiedades, necesitas hacerlo en el componente subyacente. No esperes que `next/link` pase las propiedades a sus descendientes.

En el caso anterior el descendiente del componente `Link` es la etiqueta de vínculo `<a>`.

### Vincular con un botón

Digamos que necesitas usar un botón en lugar del ancla `<a>` para tu vínculo. Entonces necesitas editar tu código de navegación así:

```html
<Link href="/help">
  <button>Help</button>
</Link>
```

Los componentes Link funcionan con cualquier cosa. Así como funciona con la etiqueta `<button>`, funciona con cualquier componente React, incluso puedes poner un `<div>` dentro de un `Link`. El único requerimiento que deben cumplir estos componentes es que deben aceptar la propiedad `onClick`.

Si deseas saber mas sobre este tema, lee la [Documentación de Ruteado de Next.js](https://nextjs.org/docs/#routing).

## Usando Componentes Compartidos

Ya que para Next.js todo se trata de páginas. Se puede crear una página exportando un componente React y colocando ese componente dentro del directorio `pages`. Entonces tendrá una URL fija basada en el nombre de archivo.

Si las páginas que se exportan son módulos JavaScript, entonces se puede importar otros componentes JavaScript dentro de ellos.

> Esta es una característica que se puede esperar de cualquier librería o framework de JavaScript.

### Crear un componente compartido

A continuación crearemos un componente de encabezado (Header) que compartiremos en múltiples páginas. Después implementaremos un componente de diseño o disposición (Layout) y veremos cómo puede ayudarnos a definir la estructura y el aspecto para las páginas que componen el sitio.

Primero creamos un directorio `components` dentro del directorio de nuestro proyecto:

```bash
$ mkdir components
```

Con un editor de texto creamos un archivo `Header.js` dentro del directorio `components` donde pondremos nuestro componente de encabezado:

```bash
$ <mi-editor-favorito> components/Header.js
```

Agregamos el siguiente código al archivo `components/Header.js`.

```javascript
// components/Header.js

import Link from 'next/link'

// En React, podemos especificar estilos CSS como objetos JavaScript
// (notese que se quitan los guiones y se capitalizan las propiedades)
// Ajustamos el margen derecho de las anclas.
const linkStyle = {
  marginRight: 15
}

const Header = () => (
  <div>
    <Link href="/">
      <a style={linkStyle}>Home</a>
    </Link>
    <Link href="/help">
      <a style={linkStyle}>Help</a>
    </Link>
  </div>
)

export default Header
```

El componente contiene dos vínculos a las páginas disponibles en nuestra aplicación. También agregamos estilo para hacerlo mas fácil de visualizar:

- `<Link href="/">`: Hace que el vínculo apunte a la ruta por defecto (componente "Index"), "/" significa "Home" y apunta a <http://localhost:3000>.
- `<a style={linkStyle}>Home</a>`: Especifica que el ancla tendrá el estilo `margin-right: 15` y el texto "Home".
- `<Link href="/about">`: Hace que el vínculo apunte a la ruta de nuestro componente `Help`, "/help" significa "Help" y apunta a <http://localhost:3000/help>.
- `<a style={linkStyle}>About</a>`: Especifica el mismo estilo para ésta ancla, y el texto "Help".
- `export default Header`: Exporta el componente `Header` para que en otro módulo podamos importarlo con la linea `import Header from '../components/Header'` y usarlo con la expresion `<Header />`.

### Usar un componente compartido

A continuación utilizaremos nuestro nuevo componente `Header` en las páginas que ya tenemos. Modificamos el módulo principal `index.js` para que utilize nuestro `Header`, quedando así:

```javascript
// pages/index.js

import Header from '../components/Header'

export default function Index() {
  return (
    <div>
      <Header />
      <p>Hello Next.js</p>
    </div>
  )
}
```

Ahora nuestro "Header" aparecerá en la página principal "Home".

> Notese que el componente `Header` se utiliza escribiendo `<Header />` Sin la etiqueta de clausura `</Header>`, esto indica que el componente no acepta descendientes como `<Link>...</Link>`.

Este componente `Header` puede utilizarse en el componente `Help`, también como encabezado. Quedando así:

```javascript
// pages/help.js

import Header from '../components/Header'

export default function Help() {
  return (
    <div>
      <Header />
      <p>This is the help page</p>
    </div>
  )
}
```

Si por ejemplo, detenemos el la aplicación `npm run dev` con `Ctrl-C`, renombramos el directorio `components` a `layouts`, cambiamos la linea `import Header from '../components/Header'` a `import Header from '../layouts/Header'` y arrancamos de nuevo la aplicación con `npm run dev`; podemos observar que nuestra aplicación sigue funcionando correctamente. Esto se debe a que no importa dónde coloques los componentes, el directorio no es especial. El único directorio que tiene un significado especial para Next.js es `pages`. Incluso puedes crear componentes dentro de `pages`, pero esto no se hace, ya que no necesitamos una URL que apunte hacia nuestros componentes, es mejor mantenerlos aparte.

### Creando un componente de disposición

Es común que en las aplicaciones web se utilice un estilo que comparten varias páginas, conservando un aspecto visual constante. Para éste propósito podemos crear un componente de diseño general (Layout), éste componente lo podemos usar en cada una de las páginas de nuestra aplicación. Por ejemplo:

Creamos un componente en el directorio `components` que se llame `components/DefaultLayout.js`:

```javascript
// components/DefaultLayout.js

import Header from './Header'

const layoutStyle = {
  margin: 20,
  padding: 20,
  border: '1px solid #DDD'
}

const Layout = props => (
  <div style={layoutStyle}>
    <Header />
    {props.children}
  </div>
)

export default Layout
```

Una vez creado nuestro componente `Layout` podemos usarlo en nuestras páginas como sigue:

```javascript
// pages/index.js

import Layout from '../components/DefaultLayout'

export default function Index() {
  return (
    <Layout>
      <p>Hello Next.js</p>
    </Layout>
  )
}
```

Y por supuesto también lo agregamos a `Help`:

```javascript
// pages/help.js

import Layout from '../components/DefaultLayout'

export default function Help() {
  return (
    <Layout>
      <p>This is the help page</p>
    </Layout>
  )
}
```

Recuerda que siempre puedes observar los cambios en el navegador accediendo a: <http://localhost:3000>

Ahora intenta remover la linea `{props.children}` en el archivo `components/DefaultLayout.js` y observa lo que sucede.

La linea que contiene `{props.children}` permite que el componente `Layout` interprete a los elementos que envuelvey los agregue al DOM. En el caso de `Index` y `Help` solo es el parrafo `<p>` correspondiente. Si omitimos `{props.children}`, `Layout` no podrá mostrar el contenido que pongamos dentro.

```javascript
// pages/help.js

import Layout from '../components/DefaultLayout'

export default function Help() {
  return (
    <Layout>
      <p>This is the help page</p> // <-- Esto no se muestra en el navegador si omites `{props.children} en `Layout`
    </Layout>
  )
}
```

### Mostrando elementos descendientes

Existen otros métodos para crear componentes de disposición:

#### Método de componente de orden superior

```javascript
// components/DefaultLayout.js

import Header from './Header'

const layoutStyle = {
  margin: 20,
  padding: 20,
  border: '1px solid #DDD'
}

const withLayout = Page => { // Función anónima de Orden Superior (Retorna/Recibe una función 'componente')
  return () => ( // Otra función anónima que retorna otro componente.
    <div style={layoutStyle}>
      <Header />
      <Page />
    </div>
  )
}

export default withLayout
```

En el ejemplo anterior podemos observar que `withLayout`, es una función cuya "prop" es otro componente, en este caso se llama `Page`. También retorna otro componente "Anónimo" que incluye a `Page` y a `Header`, además se le proporciona un estilo con `style=layoutStyle`.

El componente `withLayout` lo podemos utilizar en nuestras páginas de forma más simple:

```javascript
// pages/index.js

import withLayout from '../components/DefaultLayout'

const IndexPage = () => <p>Hello Next.js</p>

export default withLayout(IndexPage)
```

Se puede observar que en `pages/index.js` se simplificó mucho más el código. Podemos hacer lo mismo para `pages/help.js`:

```javascript
// pages/help.js

import withLayout from '../components/DefaultLayout'

const HelpPage = () => <p>This is the help page</p>

export default withLayout(HelpPage)
```

#### Método contenido como propiedad

```javascript
// components/DefaultLayout.js

import Header from './Header'

const layoutStyle = {
  margin: 20,
  padding: 20,
  border: '1px solid #DDD'
}

const Layout = props => (
  <div style={layoutStyle}>
    <Header />
    {props.content}
  </div>
)

export default Layout
```

En primera instancia parece lo mismo pero, recordemos que podemos pasar componentes como argumentos a otros componentes y retornar componentes desde componentes. Entonces, otra forma de entregar un componente a otro es la siguiente:

```javascript
// pages/index.js

import Layout from '../components/DefaultLayout'

const indexPageContent = <p>Hello Next.js</p>

export default function Index() {
  return <Layout content={indexPageContent} /> // `content` debe corresponder con `props.content`
}
```

Es importante comprender que `content` es un identificador especial que se pasa como argumento a `Layout`, es decir, todo lo que pasamos a `Layout` como propiedades `content={indexPageContent}` genera un objeto "props" similar a este:

```json
// props
{
  content: {
    <p>Hello Next.js</p>
  }
}
```

En el archivo `pages/help.js` hacemos lo mismo:

```javascript
// pages/help.js

import Layout from '../components/DefaultLayout'

const aboutPageContent = <p>This is the help page</p>

export default function Help() {
  return <Layout content={aboutPageContent} />
}
```

### Usando Componentes

Notese que todo lo que está después de `<Layout ...>` se convierte en el objeto `props`, de forma general podemos dusar componentes y propiedades como:
```html
<NombreComponente propiedad0={valor0} propiedad1={valor1} ... propiedadN={valorN} />
```

Donde `NombreComponente` puede estar definido en otro archivo o linea en el mismo archivo como:

1. Función con identificador:

```javascript
export default function NombreComponente(propiedades) {
  return ( <div>...</div> )
}
```

2. Función anónima:

```javascript
const NombreComponente = propiedades => ( <div>...</div> )
```

3. Clase que hereda React.Component:
```javascript
class NombreComponente extends React.Component {
  render() {
    return (
      <div>{this.propiedades}</div>
    )
  }
}
```

Y las `propiedades` son una coleccion de objetos de la forma:
```json
// propiedades
{
  propiedad0: {
    valor0_0,
    valor0_1,
    ...
    valor0_N
  },
  propiedad1: {
    valor1_0,
    valor1_1,
    ...
    valor1_N
  },
  {...} ... ,
  propiedadN: {
    valorN_0,
    valorN_1,
    ...
    valorN_N
  }
}
```

Toda la sintaxis anterior no es más que React. De forma más explicita, si tenemos una función con identificador, una función anónima, una clase que heredada de React.Component entonces podemos utilizarla como un componente para mostrarlo al navegador.

Existen dos casos de uso para componentes compartidos:

1. Como componentes de cabecera comunes.
2. Como disposiciones o estructura (Layouts)

Puedes usar componentes para dar estilo, definir la estructura o cualquier otra tarea que necesites. Adicionalmente puedes importar componentes desde los modulos NPM y usarlos.

## Creando Páginas Dinámicas

Ya hemos creado una aplicación Next.js básica con múltiples páginas. También ya sabemos que para crear una página, tenemos que crear un archivo real en el disco.

Sin embargo, en una aplicación real, necesitamos crear páginas dinámicamente a fín de que podamos mostrar contenido dinámico. Hay muchas formas de hacer eso con Next.js.

Comenzaremos creando páginas dinámicas usando *cadenas de consulta*.

Crearemos una simple aplicación tipo blog, la cual tiene una lista de todas las entradas en `Home` (index.js).

Cuando se dé clic al titulo de la entrada, se podrá ver la entrada de forma individual en su propia vista.

### Agregando una lista de entradas

Primero agreguemos una lista de entradas en la página `Home`. Agrega el siguiente contenido a `pages/index.js`.

```javascript
// pages/index.js
import Layout from '../components/DefaultLayout'
import Link from 'next/link'

const PostLink = props => (
  <li>
    <Link href={`/post?title=${props.title}`}>
      <a>{props.title}</a>
    </Link>
  </li>
)

export default function Blog() {
  return (
    <Layout>
      <h1>My Blog</h1>
      <ul>
        <PostLink title="Hello Next.js" />
        <PostLink title="Learn Next.js is awesome" />
        <PostLink title="Deploy apps with Zeit" />
      </ul>
    </Layout>
  )
}
```

Una vez que agregues el contenido, podrás observar una página con "My Blog" resaltado y una lista de entradas. Si das clic en una de ellas te retornará error 404 ya que no hemos escrito esa parte
del código.

### Pasando datos via cadenas de consulta

En el archivo `pages/index.js` hemos estado pasando datos a través de la cadena de parámetros de consulta. En el caso anterior, es el parámetro "title". Hacemos esto con el componente `PostLink` como se muestra a continuación:

```javascript
const PostLink = props => (
  <li>
    <Link href={`/post?title=${props.title}`}>
      <a>{props.title}</a>
    </Link>
  </li>
)
```
(Observa la propiedad `href` del componente `Link`.)

Así de fácil, puedes pasar cualquier tipo de dato que quieras a través de las cadenas de consulta.

### Crear la página "post" (entrada)

Ahora necesitamos crear la página "post" para mostrar la vista de cada entrada. Para hacer eso necesitamos obtener el título desde la cadena de consulta. Veamos como se hace eso.

Crea un archivo llamado `pages/post.js` y agrega el siguiente contenido:

```javascript
// pages/post.js
import { withRouter } from 'next/router'
import Layout from '../components/DefaultLayout'

const Page = withRouter(props => (
  <Layout>
    <h1>{props.router.query.title}</h1>
    <p>This is the blog post content.</p>
  </Layout>
))

export default Page
```

Intenta hacer clic en los titulos de las entradas, por cada entrada se mostrará su titulo y el texto "This is the blog post content.".

Esto es lo que sucede en el código anterior:

1. Importamos y usamos la función `withRouter` desde `next/router`, la cuál inyecta el ruteador Next.js como propiedad.
2. En éste caso, estamos usando el objeto `query`, que contiene los parámetros de la cadena de consulta.
3. Entonces, obtenemos la propiedad `title` con `props.router.query.title`.

Hagamos una simple modificación a nuestra aplicación. Reemplaza el contenido de `pages/post.js` con el siguiente:

```javascript
import { withRouter } from 'next/router'
import Layout from '../components/MyLayout.js'

const Content = withRouter(props => (
  <div>
    <h1>{props.router.query.title}</h1>
    <p>This is the blog post content.</p>
  </div>
))

const Page = props => (
  <Layout>
    <Content />
  </Layout>
)

export default Page
```

Ahora hemos aprendido como crear páginas dinámicas usando cadenas de consulta. Esto es sólo el comienzo.

Una página dinamica puede necesitar más información para mostrarse, y tal vez no seamos capaces de pasarla toda a través de las cadenas de consulta. Quizá deseemos tener URLs limpias como esta: `http://localhost:3000/blog/hello-nextjs`. Todo eso se verá a continuación.

## URLs Limpias y Enmascaramiento de Rutas

En la lección anterior aprendimos como crear páginas dinámicas con cadenas de consulta. Con eso, un vínculo a alguno de nuestras entradas se vé como ésta:

<http://localhost:3000/post?title=Hello%20Next.js>

Pero esa URL no se ve muy bien. Que tal si tuvieramos algo como esto?

<http://localhost:3000/p/hello-nextjs>

Sería genial, no? Eso ex exactamente lo que vamos a hacer a continuación

### Enmascaramiento de rutas

Vamos a usar una característica única de Next.js llamada "enmascaramiento de rutas" (route masking). Básicamente, mostrará una URL en el navegador, diferente a la que ve la aplicación.

Agreguemos una máscara a la URL de las entradas del blog.

Agrega el código siguiente a `pages/index.js`:

```javascript
// pages/index.js
import Layout from '../components/DefaultLayout'
import Link from 'next/link'

const PostLink = props => (
  <li>
    <Link as={`/p/${props.id}`} href={`/post?title=${props.title}`}>
      <a>{props.title}</a>
    </Link>
  </li>
)

export default function Blog() {
  return (
    <Layout>
      <h1>My Blog</h1>
      <ul>
        <PostLink id="hello-nextjs" title="Hello Next.js" />
        <PostLink id="learn-nextjs" title="Learn Next.js is awesome" />
        <PostLink id="deploy-nextjs" title="Deploy apps with Zeit" />
      </ul>
    </Layout>
  )
}
```

Si observamos el bloque de código:

```javascript
const PostLink = props => (
  <li>
    <Link as={`/p/${props.id}`} href={`/post?title=${props.title}`}>
      <a>{props.title}</a>
    </Link>
  </li>
)
```

En el elemento `<Link>`, utilizamos otra propiedad llamada `as`. Esta propiedad es la que necesitamos mostrar en el navegador. La URL que la aplicación ve se menciona en la propiedad `href`.

Ahora haz clic en el titulo de cualquier entrada del blog y te llevará a la entrada.

Después haz clic en el botón *back* y después *foward* para que puedas observar el historial.

### Atención al historial

Hemos presenciado que el enmascaramiento de rutas trabaja muy bien con el historial del navegador. Todo lo que tienes que hacer es agregar la propiedad `as` al link.

### Recargar la página

Ve a la página "home": <http://localhost:3000> y da clic en el título de la primer entrada. Esto te llevará a la página de la entrada. Después refresca la ventana del navegador y observa como arrojará un error 404.

### Error 404

La razón por la que al refrescar retorna 404 es por que no hay tal página en el servidor. El sevidor tratará de cargar la página `p/hello-nextjs`, pero solo tenemos 3 páginas: `index.js`, `about.js` y `post.js`.

Con este error no podemos correr la aplicación en producción. Necesitamos resolver el problema.

*La [API personalizada de servidor](https://github.com/zeit/next.js#custom-server-and-routing) de Next.js es la solución a este problema.*

## Soporte para URLs Limpias del Lado del Servidor

Anteriormente aprendimos como crear URLs para nuestra aplicación. Básicamente, podemos tener URLs como esta:

<http://localhost:3000/p/my-blog-post>

Pero esto funcionó navegando del lado del cliente. Cuando recargamos la página, nos retornó un error 404. Esto es por que no existe una página llamada `p/my-blog-post` en el directorio `pages`.

Podemos resolver esto de forma muy fácil con la [API personalizada de servidor Next.js](https://github.com/zeit/next.js#custom-server-and-routing). Veamos como podemos hacer esto.

### Crear un servidor personalizado

Para crear nuestro servidor personalizado usaremos [Express](https://expressjs.com), ya que es muy sencillo de usar.

Primero, instalamos Express en nuestra aplicación:
```bash
$ npm install --save express
```

Después crea un archivo `server.js` en el directorio principal del proyecto y agrega el siguiente código:

```javascript
// server.js
const express = require('express')
const next = require('next')

const dev = process.env.NODE_ENV !== 'production'
const app = next({ dev })
const handle = app.getRequestHandler()

app.prepare()
  .then(() => {
    const server = express()

    server.get('*', (req, res) => {
      return handle(req, res)
    })

    server.listen(3000, err => {
      if (err) throw err
      console.log('> Ready on http://localhost:3000')
    })
  }).catch(ex => {
    console.error(ex.stack)
    process.exit(1)
  })
```

A continuación actualiza el script `npm run dev` en `package.json` para que quede así:

```javascript
{
  "scripts": {
    "dev": "node server.js",
    "build": "next build",
    "start": "NODE_ENV=production node server.js"
  }
}
```

Ahora puedes ejecutar la aplicación con `npm run dev`. Aunque la aplicación funcionará, todavía no funcionarán las rutas limpias del lado del servidor.

### Crear nuestra Ruta Personalizada

Como pudiste experimentar, la aplicación funciona exactamente igual a la versión (serverless) ya que el servidor personalizado que escribimos funciona de forma similar al comando `next`.

Ahora vamos a agregar una ruta personalizada que coincida con las URL de las entradas en el blog.

Con la nueva ruta, nuestro `server.js` se verá como sigue:
```javascript
// server.js
const express = require('express')
const next = require('next')

const dev = process.env.NODE_ENV !== 'production'
const app = next({ dev })
const handle = app.getRequestHandler()

app.prepare()
  .then(() => {
    const server = express()

    server.get('/p/:id', (req, res) => {
      const actualPage = '/post'
      const queryParams = { title: req.params.id }
      app.render(req, res, actualPage, queryParams)
    })

    server.get('*', (req, res) => {
      return handle(req, res)
    })

    server.listen(3000, err => {
      if (err) throw err
      console.log('> Ready on http://localhost:3000')
    })
  }).catch(ex => {
    console.error(ex.stack)
    process.exit(1)
  })

```

Echemos un vistazo al código nuevo:

```javascript
server.get('/p/:id', (req, res) => {
  const actualPage = '/post'
  const queryParams = { title: req.params.id }
  app.render(req, res, actualPage, queryParams)
})
```

Aquí simplemente mapeamos una ruta personalizada a nuestra página existente "/post". También mapeamos los parámetros de consulta.

Reinicia la aplicación y visita la página siguiente:

<http://localhost:3000/p/hello-nextjs>

Ya no verás la página 404, sino la entrada del blog. Aunque hay un pequeño problema, el título del lado del cliente y el título del lado del servidor son diferentes.


### Información en la URL

La página `/post` acepta el título a través del parametro `title` en la cadena de consulta. En el lado de enrutado del lado del cliente, podemos darle un valor adecuado enmascarando la URL (usando la propiedad `as`).

```javascript
<Link as={`/p/${props.id}`} href={`/post?title=${props.title}`}>
  <a>{props.title}</a>
</Link>
```

Pero en la ruta del servidor, no tenemos ese título porque sólo tenemos un ID para la entrada del blog en la URL. En ese caso, ponemos el ID como un parámetro de la cadena de consulta del lado del servidor.

Se puede observar en la definición de la ruta:

```javascript
server.get('/p/:id', (req, res) => {
  const actualPage = '/post'
  const queryParams = { title: req.params.id }
  app.render(req, res, actualPage, queryParams)
})
```

Esto es un problema. Pero en la vida real, esto no es grave porque usamos el ID para obtener datos del servidor, en ambos lados, cliente y servidor. Así que solo necesitamos un ID.

Siempre puedes crear tantas rutas como quieras, si deseas profundizar mas en la utilización de servidores con Next.js visita la documentación de la [API personalizada de servidor Next.js](https://github.com/zeit/next.js#custom-server-and-routing)

## Obteniendo Datos para las Páginas

## Dando Estilo a Componentes

## Desplegando una Aplicación Next.js

## Referencias

[1]: https://developer.mozilla.org/es/docs/Tools/Page_Inspector#Abriendo_el_Inspector
